﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using NLog;
using System;
using System.IO;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Casamiel.API
{
    /// <summary>
    /// 
    /// </summary>
    public static class stringE
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string GetMd5String(this string str)
        {
            if (String.IsNullOrEmpty(str))
            {
                throw new BizException("字符串不能为空");
            }
            using (var md5 = MD5.Create())
            {
                var rst = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
                return BitConverter.ToString(rst).Replace("-", "").ToUpper();
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ToJsonString(this object obj)
        {
            if (obj == null)
            {
                throw new BizException("序列化成json的对象不能为空");
            }
            return JsonConvert.SerializeObject(obj, new JsonSerializerSettings() { MaxDepth = 3 });
        }
    }
    /// <summary>
    /// 
    /// </summary>
    public class ApiExceptionFilterAttribute : ExceptionFilterAttribute
    {
        private const string MSG = "网络异常，请重试";
        /// <summary>
        /// 
        /// </summary>
        private readonly NLog.ILogger logger;
        /// <summary>
        /// 
        /// </summary>
        private readonly ILogger bizLogger;
        /// <summary>
        /// 
        /// </summary>
        public ApiExceptionFilterAttribute()
        {
            this.logger = LogManager.GetCurrentClassLogger();
            this.bizLogger = LogManager.GetLogger("bizError");
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="logger"></param>
        protected ApiExceptionFilterAttribute(ILogger logger)
        {
            this.logger = logger;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async override Task OnExceptionAsync(ExceptionContext context)
        {
            var reqBody = "";
            var path = context.HttpContext.Request.Path.ToString();
            if (context.HttpContext.Request.Method == HttpMethod.Post.ToString())
            {
                context.HttpContext.Request.Body.Seek(0, SeekOrigin.Begin);
                using (var sr = new StreamReader(context.HttpContext.Request.Body))
                {
                    reqBody = await sr.ReadToEndAsync();
                    reqBody = reqBody.Replace("\r", "").Replace("\n", "");
                }
            }

            context.ExceptionHandled = true;
            if (context.Exception is BizException)
            {
                var bizError = context.Exception as BizException;
                context.Result = new ContentResult() { Content = new { msg = bizError.BizMsg, success = false }.ToJsonString(), ContentType = "application/json", StatusCode = 400 };
                bizLogger.Info(bizError, () =>
                {
                    return $"业务异常，地址{path},参数{reqBody},异常信息: {bizError.BizMsg},{bizError.HiddenMsg}";
                });
            }
            else if (context.Exception is DbUpdateException)
            {
                var dbError = context.Exception as DbUpdateException;
                context.Result = new ContentResult() { Content = new { msg = MSG, success = false }.ToJsonString(), ContentType = "application/json", StatusCode = 500 };
                logger.Error(dbError, () =>
                {
                    return $"数据库异常,地址{path},参数{reqBody},异常信息:{dbError.Message},{dbError.InnerException?.Message},{dbError.StackTrace}";
                });
            }
            // else if (context.Exception is TokenExpireException)
            // {
            //     var tokenExpireException = context.Exception as TokenExpireException;
            //     context.Result = new ContentResult(){Content = new {msg = "登录过期", success = false}.ToJsonString(), ContentType = "application/json",StatusCode= 500};
            //     logger.Error(tokenExpireException,()=>{
            //         return $"登录超时";
            //     });
            // }
            else
            {
                var ex = context.Exception;
                context.Result = new ContentResult() { Content = new { msg = MSG, success = false }.ToJsonString(), ContentType = "applicatio/json", StatusCode = 500 };
                logger.Error(ex, () =>
                {
                    return $"系统异常，地址{path},参数{reqBody},异常信息:{ex.Message},{ex.StackTrace}";
                });
            }

        }
    }
}